package ShardSystem;

import java.util.ArrayList;

/**
 *
 * @author David
 */
public class GameOfShards {
    
    static int grid_margin                   = 2;                   // Margin on right and bottom of grid
    static int grid_size_x                   = 0,                   // Grid size X
               grid_size_y                   = 0;                   // Grid size Y
    static Grid grid                         = new Grid(0, 0);      // Grid
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        // Validate grid sizes
        if(args.length > 0 && args.length <= 2) {
            try {
                grid_size_x = Integer.parseInt(args[0]);
                try {
                grid_size_y = Integer.parseInt(args[1]);
                } catch(Exception e) {
                    System.out.println("Invalid argument for grid_size_y at index 1 " + e);
                    System.exit(1);
                }
            } catch(Exception e) {
                System.out.println("Invalid argument for grid_size_x at index 0 " + e);
                System.exit(1);
            }
        }
        
        // Create storage for game objects
        ArrayList products = new ArrayList();
        ArrayList traders  = new ArrayList();
        ArrayList cities   = new ArrayList();
        
        // Create products
        Product tea    = new Product("tea", 300);
        products.add(tea);
        Product prawn  = new Product("prawn", 1400);
        products.add(prawn);
        Product cake   = new Product("cake", 800);
        products.add(cake);
        Product curry  = new Product("curry", 150);
        products.add(curry);
        Product petrol = new Product("petrol", 800000);
        products.add(petrol);
        Product orange = new Product("orange", 130);
        products.add(orange);
        Product apple  = new Product("apple", 120);
        products.add(apple);
        
        // Create traders
        Trader trader_donkeyman = new Trader("DonkeyMan", 5000, 4, 4);
        traders.add(trader_donkeyman);
    
        trader_donkeyman.getProducts().add(new ProductListItem(prawn, 20));
        trader_donkeyman.getProducts().add(new ProductListItem(tea, 100));
        
        traders.add(new Trader("SteveTheTrader", 2500, 4, 4));
        traders.add(new Trader("LonesomeBob", 1500, 3, 1));
        traders.add(new Trader("LonesomeBob", 1500, 8, 4));
        
        // Create cities
        City city_nyc = new City("New York", 3, 3);
        city_nyc.getProductList().add(new ProductListItem(tea, 1000));
        cities.add(city_nyc);
        
        City city_london = new City("London", 7, 9);
        city_london.getProductList().add(new ProductListItem(tea, 5000));
        city_london.getProductList().add(new ProductListItem(petrol, 600));
        city_london.getProductList().add(new ProductListItem(cake, 150));
        cities.add(city_london);
        
        cities.add (new City("Shanghai", 2, 4));
        cities.add (new City("Tokyo", 4, 4));
        cities.add (new City("Singapore", 6, 9));
        cities.add (new City("Baghdad", 6, 1));
                
        
        // Check cities and traders storage for largest x and y location
        // and reassign grid size appropriately
        for(int i = 0; i < cities.size(); i++) {
            City currentCity = (City)(cities.get(i));
            if (currentCity.getLocation_x() > grid_size_x) {
                grid_size_x = currentCity.getLocation_x();
            }
            if (currentCity.getLocation_y() > grid_size_y) {
                grid_size_y = currentCity.getLocation_y();
            }
        }
        for(int i = 0; i < traders.size(); i++) {
            Trader currentTrader = (Trader)(traders.get(i));
            if (currentTrader.getLocation_x() > grid_size_x) {
                grid_size_x = currentTrader.getLocation_x();
            }
            if (currentTrader.getLocation_y() > grid_size_y) {
                grid_size_y = currentTrader.getLocation_y();
            }
        }
        if(grid_size_x == 0) {
            System.out.println("Invalid grid size.");
            System.exit(1);
        } else if(grid_size_y == 0) {
            System.out.println("Invalid grid size.");
            System.exit(1);
        } else {
            // Add margin and index offset (sizes are 1-offset, locations are 0-offset) to grid sizes
            grid_size_x += 1 + grid_margin;
            grid_size_y += 1 + grid_margin;
            
            // Create grid
            grid = new Grid(grid_size_x, grid_size_y);
        }
        
        System.out.println("====== GAME OF SHARDS ======");
     
        // Print out list of products
        System.out.println("------- Product List -------");
        if( products.isEmpty()) {
            System.out.println(">> No products");
        } else {
            for(int i = 0; i < products.size(); i++) {
                Product currentProduct = (Product)(products.get(i));
                System.out.println(currentProduct.getName() + " " + currentProduct.getPrice());
            }
        }
        // Print out list of traders
        System.out.println("------- Traders List -------");
        if( traders.isEmpty()) {
            System.out.println(">> No traders");
        } else {
            for(int i = 0; i < traders.size(); i++) {
                Trader currentTrader = (Trader)(traders.get(i));
                System.out.println(currentTrader.getName() + " " + currentTrader.getBalance() + " (" + currentTrader.getLocation_x() + "," + currentTrader.getLocation_y() + ")");
                grid.addToGrid(currentTrader.getLocation_x(), currentTrader.getLocation_y(), currentTrader);

                // Print out list of traders' products
                if(currentTrader.getProducts().isEmpty()) {
                    System.out.println("   >> No products");
                } else {
                    for(int j = 0; j < currentTrader.getProducts().size(); j++) {
                        ProductListItem currentProductListItem = (ProductListItem)(currentTrader.getProducts().get(j));
                        System.out.println("   " + currentProductListItem.getProduct().getName() + " " + currentProductListItem.getQuantity());
                    }
                }
            }
        }
 
        // Print out list of cities
        System.out.println("-------- City  List --------");
        if( cities.isEmpty()) {
            System.out.println(">> No cities");
        } else {
            for(int i = 0; i < cities.size(); i++) {
                City currentCity = (City)(cities.get(i));
                System.out.println(currentCity.getName() + " (" + currentCity.getLocation_x() + "," + currentCity.getLocation_y() + ")");
                grid.addToGrid(currentCity.getLocation_x(), currentCity.getLocation_y(), currentCity);

                // Print out list of cities' products
                if(currentCity.getProductList().isEmpty()) {
                    System.out.println("   >> No products");
                } else {
                    for(int j = 0; j < currentCity.getProductList().size(); j++) {
                        ProductListItem currentProductListItem = (ProductListItem)(currentCity.getProductList().get(j));
                        System.out.println("   " + currentProductListItem.getProduct().getName() + " " + currentProductListItem.getQuantity());
                    }
                }
            }
        }
        
        System.out.println();
        
        // DEBUG Print GridObject classes 
//        for(int i = 0; i < grid.getGrid().length; i++) {
//            for( int j = 0; j < (grid.getGrid())[i].length; j++) {
//                //System.out.print(j + "," + i  + "; " + ((GridObject)(grid.getGrid()[i][j])).getClass().getName() + "; ");
//                if(grid.getGrid()[i][j].isEmpty()) {
//                    System.out.print(j + "," + i + "; Empty; \t");
//                } else {
//                    for(int k = 0; k < grid.getGrid()[i][j].size(); k++) { 
//                        System.out.print(j + "," + i  + "; " + ((GridObject)(grid.getGrid()[i][j]).get(k)).getName() + "; ");
//                    }
//                    System.out.print("\t");
//                }
//            }
//            System.out.println();
//        }
//        System.out.println(); 
        
        // Print the grid
         System.out.println("-------- Le monde --------");
        for(int i = 0; i < grid_size_x * 3 - 1; i++) {
            for( int j = 0; j < grid_size_y * 3 - 1; j++) {
                //GridObject currentGridObject = (GridObject)((grid.getGrid())[i/3][j/3]);
                ArrayList objectsAtCurrentGridSquare = ((grid.getGrid())[i/3][j/3]);
                // Print grid separating lines
                if( (i + 1) % 3 == 0 && (j + 1) % 3 == 0) { 
                    System.out.print("+");
                } else if((i + 1) % 3 != 0 && (j + 1) % 3 == 0) {
                    System.out.print("|");
                } else if((i + 1) % 3 == 0 && (j + 1) % 3 != 0) {
                    System.out.print("-");

                // Print grid contents
                } else if((i % 3 == 0) && (j % 3 == 0)) {
                    boolean isCity = false;
                    for(int k = 0; k < objectsAtCurrentGridSquare.size(); k++) {
                        if(((GridObject)(objectsAtCurrentGridSquare.get(k))).getClass() == City.class) {
                            isCity = true;
                            break;
                        }
                    }
                    System.out.print(isCity ? "C" : " "); 
                } else if((i % 3 == 0) && (j % 3 == 1)) {
                    int countTraders = 0;
                    for(int k = 0; k < objectsAtCurrentGridSquare.size(); k++) {
                        if(((GridObject)(objectsAtCurrentGridSquare.get(k))).getClass() == Trader.class) {
                            countTraders++;
                        }
                    }
                    System.out.print(countTraders > 0 && countTraders <= 9 ? countTraders : " "); 
                    
                // Empty square
                } else {
                    System.out.print(" ");
                }
            }
            System.out.println();
        }
        
        // End
        System.out.println();
        System.out.println("==== GAME OVER ====");
        System.out.println();
    }
}
